#ifndef NETWORKMANAGER_H
#define NETWORKMANAGER_H

#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QUdpSocket>
#include <QHostAddress>
#include <QByteArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QList>
#include <QMetaObject>
#include <functional>

#include "../logging/logger.h"

// 定义消息类型
enum class MessageType {
    Connect,           // 连接请求
    Authenticate,      // 身份验证
    ScreenData,        // 屏幕数据
    MouseEvent,        // 鼠标事件
    KeyboardEvent,     // 键盘事件
    AudioData,         // 音频数据
    AudioFormat,       // 音频格式
    SystemInfo,        // 系统信息
    Disconnect,        // 断开连接
    Heartbeat,         // 心跳包
    Error,             // 错误消息
    FileSendRequest,   // 文件发送请求
    FileSendData,      // 文件数据块
    FileSendFinish,    // 文件发送完成
    FileSendAck        // 文件数据块确认
};

class NetworkManager : public QObject
{
    Q_OBJECT

public:
    explicit NetworkManager(QObject *parent = nullptr);
    virtual ~NetworkManager();

    // 连接到指定服务器
    virtual bool connectToHost(const QString &host, quint16 port);
    
    // 断开连接
    virtual void disconnectFromHost();
    
    // 发送数据
    virtual bool sendData(MessageType type, const QJsonObject &data);
    
    // 检查连接状态
    bool isConnected() const;
    
    // 注册临时消息处理函数
    template<typename Func>
    void registerTemporaryHandler(Func handler) {
        // 存储处理函数
        tempHandlers.push_back(handler);
        
        // 连接到我们自己的槽函数
        QMetaObject::Connection conn = connect(this, &NetworkManager::dataReceived, 
                 this, &NetworkManager::handleTemporaryMessages);
                 
        // 存储连接，以便以后可以断开
        tempConnections.push_back(conn);
    }

signals:
    // 连接状态变化信号
    void connectionStatusChanged(bool connected);
    
    // 接收数据信号
    void dataReceived(MessageType type, const QJsonObject &data);
    
    // 错误信号
    void errorOccurred(const QString &errorMsg);

protected:
    QTcpSocket *tcpSocket;
    QUdpSocket *udpSocket;
    QByteArray receiveBuffer;  // 接收数据缓冲区
    
    // 处理接收到的数据
    virtual void processReceivedData(const QByteArray &data);
    
    // 将消息类型转换为字符串
    QString messageTypeToString(MessageType type);
    
    // 将字符串转换为消息类型
    MessageType stringToMessageType(const QString &typeStr);
    
private:
    // 存储临时处理函数和连接
    QList<QMetaObject::Connection> tempConnections;
    QList<std::function<bool(MessageType, const QJsonObject&)>> tempHandlers;
    
    // 处理临时消息处理函数
    void handleTemporaryMessages(MessageType type, const QJsonObject &data) {
        // 创建要保留的处理函数和连接的新列表
        QList<std::function<bool(MessageType, const QJsonObject&)>> remainingHandlers;
        QList<QMetaObject::Connection> remainingConnections;
        
        // 标记是否有处理函数处理了此消息
        bool messageHandled = false;
        
        // 遍历所有处理函数
        for (int i = 0; i < tempHandlers.size(); ++i) {
            // 调用处理函数
            bool handled = tempHandlers[i](type, data);
            
            // 如果处理函数返回true，表示它已处理消息
            if (handled) {
                messageHandled = true;
                
                // 断开连接
                if (i < tempConnections.size()) {
                    disconnect(tempConnections[i]);
                }
            } else {
                // 否则，将处理函数和连接保留
                remainingHandlers.push_back(tempHandlers[i]);
                if (i < tempConnections.size()) {
                    remainingConnections.push_back(tempConnections[i]);
                }
            }
        }
        
        // 更新处理函数和连接列表
        tempHandlers = remainingHandlers;
        tempConnections = remainingConnections;
        
        // 如果没有处理函数处理此消息，保持连接
        if (!messageHandled && tempConnections.isEmpty() && !tempHandlers.isEmpty()) {
            // 如果有处理函数但没有连接，重新连接
            QMetaObject::Connection conn = connect(this, &NetworkManager::dataReceived, 
                     this, &NetworkManager::handleTemporaryMessages);
            tempConnections.push_back(conn);
        }
    }
};

#endif // NETWORKMANAGER_H 